/**
 * @file list.h
 * Estrutura de dados do tipo Lista de Jobs.
 */

#ifndef LIST_H_
#define LIST_H_

#include "job.h"

/**
 * Iterador da lista.
 */
typedef struct node {
	Job data;
	struct node *next, *prev;
} Node;

/**
 * Estrutura de lista.
 */
typedef struct list {
	Node *begin, *end;
	int len;
} List;


/**
 * Lista de processos agendados (global).
 */
extern List schedule;


/**
 * Lista de processos em execução no momento (global).
 */
extern List running;


/**
 * Inicializa uma lista.
 *
 * @param list A estrutura do tipo List que será inicializada.
 * @return O mesmo ponteiro que foi passado como parâmetro.
 *
 * Essa função não aloca memória para a lista, por isso recebe a estrutura como
 * parâmetro. Ela retorna o mesmo ponteiro por conveniência, para que você possa
 * fazer <b>List *l = list_new(malloc(sizeof(List)));</b>.
 */
List *list_new(List *list);

/**
 * Destrói uma lista.
 *
 * @param list A lista a ser destruída.
 * @return Um ponteiro para a própria lista passada como parâmetro.
 *
 * Essa função não remove a memória alocada para a estrutura List, mas remove a
 * memória alocada para todos os nós da lista. Por conveniência, retorna a
 * própria lista, para que você possa fazer <b>free(list_del(l));</b>.
 */
List *list_del(List *list);

/**
 * Acresenta dados na lista.
 *
 * @param list A lista onde o dado será inserido.
 * @param position Um iterador indicando em que posição o dado será inserido.
 * @param data O dado a ser inserido na lista.
 * @return Um iterador para o novo elemento inserido.
 *
 * Essa função insere um novo nó na lista na posição indicada pelo iterador
 * position. O conteúdo desse nó não é alterado, apenas a sua posição. O dado a
 * ser inserido é passado por ponteiro e será copiado, sendo assim, o dado
 * original permanece intacto.
 */
Node *list_add(List *list, Node *position, const Job *data);

/**
 * Remove um elemento da lista.
 *
 * @param list A lista de onde o elemento será removido.
 * @param position Um iterador indicando qual elemento deve ser removido.
 * @return Um iterador para o elemento logo após ao que foi removido.
 *
 * Essa função apaga o nó e o dado que estavam na posição indicada, sendo assim,
 * logo após sua invocação o ponteiro position estará inválido. Porém, um
 * ponteiro para o próximo elemento é retornado, para que você possa corrigir o
 * ponteiro inválido.
 */
Node *list_rem(List *list, Node *position);

#endif /* LIST_H_ */
